#include "serialthread.h"
#include <QDebug>
#include "databuffer.h"

SerialThread::SerialThread( const QString &deviceName, QObject *parent ) : QObject{ parent }, _is_open( false ), _device_name( deviceName )
{
    this->moveToThread( &_thread );
    connect( &_thread, &QThread::started, this, &SerialThread::doSomething, Qt::DirectConnection );
    _thread.start();
}

SerialThread::~SerialThread()
{
    _thread.quit();
    _thread.wait();
}

void SerialThread::open()
{
    emit sigOpenSerial();
}

void SerialThread::close()
{
    emit sigCloseSerial();
}

bool SerialThread::isOpen() const
{
    return _is_open;
}

void SerialThread::onOpenSerial()
{
    QMutexLocker locker( &_mutex );
    if ( !_serial_port->isOpen() ) {
        if ( !_serial_port->open( QIODevice::ReadWrite ) ) {
            qDebug() << _serial_port->portName() << "open fail";
        }
        else {
            qDebug() << _serial_port->portName() << "open success";
        }
    }
    _is_open = _serial_port->isOpen();
}

void SerialThread::onCloseSerial()
{
    if ( _serial_port->isOpen() ) {
        _serial_port->close();
    }
    _is_open = _serial_port->isOpen();
}

void SerialThread::doSomething()
{
    QMutexLocker locker( &_mutex );

    _serial_port.reset( new QSerialPort( _device_name ) );
    connect( _serial_port.get(), &QSerialPort::readyRead, this, &SerialThread::onReadyRead );
    connect( this, &SerialThread::sigOpenSerial, this, &SerialThread::onOpenSerial, Qt::QueuedConnection );
    connect( this, &SerialThread::sigCloseSerial, this, &SerialThread::onCloseSerial, Qt::QueuedConnection );

    _serial_port->setBaudRate( 9600 );
    _serial_port->setDataBits( QSerialPort::Data8 );
    _serial_port->setStopBits( QSerialPort::OneStop );
    _serial_port->setParity( QSerialPort::NoParity );

    //    onOpenSerial();
    //        if ( !_serial_port->open( QIODevice::ReadWrite ) ) {
    //            qDebug() << _serial_port->portName() << "open fail";
    //        }
    //        else {
    //            qDebug() << _serial_port->portName() << "open success";
    //        }
}

void SerialThread::onReadyRead()
{
    QByteArray recvdata = _serial_port->readAll();
    if ( !recvdata.isEmpty() ) {
        auto &data_buffer = DataBuffer::instance();
        qDebug() << _serial_port->portName() << "RX:" << recvdata.toHex( ' ' );
        QByteArray writeData;
        if ( data_buffer.matchDataValue( recvdata, writeData ) ) {
            qDebug() << _serial_port->portName() << "TX:" << writeData.toHex( ' ' );
            _serial_port->write( writeData );
            _serial_port->flush();
            //            _serial_port->waitForBytesWritten();
        }
    }
}
